package com.ds.plugins.action;

import com.ds.annotation.Aggregation;
import com.ds.annotation.AggregationType;
import com.ds.annotation.Split;
import com.ds.annotation.UserSpace;
import com.ds.common.JDSException;
import com.ds.common.logging.ChromeProxy;
import com.ds.config.ErrorResultModel;
import com.ds.config.ResultModel;
import com.ds.context.JDSActionContext;
import com.ds.esd.annotation.CustomAction;
import com.ds.esd.annotation.CustomAnnotation;
import com.ds.esd.annotation.MenuBarMenu;
import com.ds.esd.annotation.event.ActionTypeEnum;
import com.ds.esd.annotation.event.CustomBeforInvoke;
import com.ds.esd.annotation.event.CustomCallBack;
import com.ds.esd.annotation.event.CustomOnExecueSuccess;
import com.ds.esd.annotation.field.APIEventAnnotation;
import com.ds.esd.annotation.menu.CustomMenuType;
import com.ds.esd.annotation.ui.ComponentType;
import com.ds.esd.annotation.ui.RequestPathEnum;
import com.ds.esd.bean.CustomViewBean;
import com.ds.esd.bean.MethodConfig;
import com.ds.esd.custom.CustomViewFactory;
import com.ds.esd.dsm.BuildFactory;
import com.ds.esd.dsm.DSMFactory;
import com.ds.esd.dsm.aggregation.DomainInst;
import com.ds.esd.dsm.java.AggRootBuild;
import com.ds.esd.engine.ESDFacrory;
import com.ds.esd.engine.EUModule;
import com.ds.esd.tool.DSMProperties;
import com.ds.esd.tool.component.Component;
import com.ds.esd.tool.component.ModuleComponent;
import com.ds.esd.util.XUIUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;


@Controller
@RequestMapping(value = {"/action/module/build/"})
@MenuBarMenu(menuType = CustomMenuType.TOP, caption = "模块编译", index = 1, imageClass = "spafont spa-icon-alignw")
@Aggregation(type = AggregationType.MENU, userSpace = UserSpace.SYS)
public class MobuleBuildAction {
    public MobuleBuildAction() {

    }


    @Split
    @CustomAnnotation(index = 2)
    @ResponseBody
    public ResultModel<Boolean> split() {
        ResultModel resultModel = new ResultModel();
        return resultModel;
    }


    @RequestMapping(method = RequestMethod.POST, value = "rebuildModuleView")
    @CustomAnnotation(index = 0, caption = "创建模型", imageClass = "xuicon xui-uicmd-add")
    @APIEventAnnotation(customRequestData = {RequestPathEnum.SPA_PROJECTNAME, RequestPathEnum.SPA_CLASSNAME},
            beforeInvoke = CustomBeforInvoke.BUSY,
            afterInvok = CustomCallBack.FREE,
            afterInvokAction = @CustomAction(name = "reloadPage", method = "call", type = ActionTypeEnum.other, target = "callback", args = {"{SPA.reloadPage()}"}),
            onExecuteSuccess = {CustomOnExecueSuccess.MESSAGE}
    )
    @ResponseBody
    public ResultModel<Boolean> rebuildModuleView(String currentClassName, String projectName) {
        ResultModel<Boolean> result = new ResultModel<>();
        try {
            DomainInst domainInst = DSMFactory.getInstance().getDefaultDomain(projectName, UserSpace.VIEW);
            Map<String, Object> ctxMap = new HashMap<>();
            ctxMap.put("domainId", domainInst.getDomainId());
            JDSActionContext.getActionContext().getContext().putAll(ctxMap);
            EUModule euModule = ESDFacrory.getAdminESDClient().getModule(currentClassName, projectName);
            ModuleComponent moduleComponent = euModule.getComponent();
            MethodConfig methodConfig = null;
            try {
                methodConfig = moduleComponent.getMethodAPIBean();
                if (methodConfig == null) {
                    methodConfig = ESDFacrory.getAdminESDClient().getMethodAPIBean(euModule.getPath(), projectName);
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
            CustomViewBean viewBean = null;
            if (methodConfig == null) {
                viewBean = DSMFactory.getInstance().getViewManager().getDefaultViewBean(moduleComponent, domainInst.getDomainId());
            } else {
                viewBean = methodConfig.getView();
                viewBean.updateModule(euModule.getComponent());
            }
            AggRootBuild aggRootBuild = BuildFactory.getInstance().getAggRootBuild(viewBean, euModule.getClassName(), projectName);
            aggRootBuild.build();
            if (methodConfig == null) {
//                AggViewRoot viewRoot = new AggViewRoot(domainInst, euModule.getClassName(), viewBean.getModuleBean());
//                DSMFactory.getInstance().getAggregationManager().genAggViewJava(viewRoot, viewBean, euModule.getClassName(), getCurrChromeDriver());
                methodConfig = moduleComponent.getMethodAPIBean();
            }
            euModule.getComponent().getProperties().setDsmProperties(new DSMProperties(methodConfig, projectName));
            euModule.update(false);
        } catch (JDSException e) {
            e.printStackTrace();
        }


        return result;
    }


    @RequestMapping(value = {"buildView"}, method = {RequestMethod.POST})
    @APIEventAnnotation(customRequestData = {RequestPathEnum.SPA_PROJECTNAME, RequestPathEnum.SPA_CLASSNAME},
            beforeInvoke = CustomBeforInvoke.BUSY,
            afterInvok = CustomCallBack.FREE,
            afterInvokAction = @CustomAction(name = "reloadPage", method = "call", type = ActionTypeEnum.other, target = "callback", args = {"{SPA.reloadPage()}"}),
            onExecuteSuccess = {CustomOnExecueSuccess.MESSAGE}
    )
    @CustomAnnotation(index = 1, caption = "编译视图", imageClass = "spafont spa-icon-moveforward")
    @ResponseBody
    public ResultModel<Boolean> buildView(String projectName, String currentClassName) {
        ResultModel resultModel = new ResultModel();
        ChromeProxy chrome = getCurrChromeDriver();
        try {
            DomainInst domainInst = DSMFactory.getInstance().getDefaultDomain(projectName, UserSpace.VIEW);
            Map<String, Object> ctxMap = new HashMap<>();
            ctxMap.put("domainId", domainInst.getDomainId());
            JDSActionContext.getActionContext().getContext().putAll(ctxMap);
            EUModule euModule = ESDFacrory.getAdminESDClient().getModule(currentClassName, projectName);
            ModuleComponent moduleComponent = euModule.getComponent();
            MethodConfig methodConfig = null;
            try {
                methodConfig = moduleComponent.getMethodAPIBean();
                if (methodConfig == null) {
                    methodConfig = ESDFacrory.getAdminESDClient().getMethodAPIBean(euModule.getPath(), projectName);
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }

            EUModule module = ESDFacrory.getAdminESDClient().getModule(methodConfig.getUrl(), domainInst.getProjectVersionName());
            if (module != null) {
                if (euModule != null) {
                    Component component = euModule.getComponent().findComponentByFieldName(XUIUtil.formatJavaName(methodConfig.getView().getName(), true));
                    if (component == null) {
                        component = euModule.getComponent().findComponentByFieldName(XUIUtil.formatJavaName(methodConfig.getName(), true));
                    }
                    if (component != null && !(component instanceof ModuleComponent)) {
                        Component currComponent = module.getComponent().getCurrComponent().clone();
                        currComponent.setEvents(component.getEvents());
                        Component parent = component.getParent();
                        parent.removeChildren(component);
                        parent.addChildren(currComponent);
                        euModule.update(true);
                    }

                }
                List<ModuleComponent> moduleComponents = module.getComponent().findComponents(ComponentType.MODULE, null);
                for (ModuleComponent childModule : moduleComponents) {
                    if (childModule.getEuModule() != null) {
                        ESDFacrory.getAdminESDClient().delModule(childModule.getEuModule());
                    }
                }
                ESDFacrory.getAdminESDClient().delModule(module);
            }
            JDSActionContext.getActionContext().getContext().put(CustomViewFactory.TopModuleKey, null);
            JDSActionContext.getActionContext().getContext().put(CustomViewFactory.CurrModuleKey, null);
            CustomViewFactory.getInstance().buildView(methodConfig, domainInst.getProjectVersionName(), (Map<String, ?>) JDSActionContext.getActionContext().getContext(), false);
            CustomViewFactory.getInstance().reLoad();
        } catch (Exception e) {
            e.printStackTrace();
            chrome.printError(e.getMessage());
            ((ErrorResultModel) resultModel).setErrdes(e.getMessage());
        }
        return resultModel;
    }

    @RequestMapping(value = {"clear"}, method = {RequestMethod.POST})
    @APIEventAnnotation(customRequestData = {RequestPathEnum.SPA_PROJECTNAME, RequestPathEnum.CTX},
            beforeInvoke = CustomBeforInvoke.BUSY,
            callback = CustomCallBack.FREE
    )
    @CustomAnnotation(index = 3, caption = "重置", imageClass = "spafont spa-icon-resetpath")
    @ResponseBody
    public ResultModel<Boolean> clear(String projectName, String currentClassName) {
        ResultModel resultModel = new ResultModel();
        ChromeProxy chrome = getCurrChromeDriver();
        try {
            DomainInst domainInst = DSMFactory.getInstance().getDefaultDomain(projectName, UserSpace.VIEW);
            Map<String, Object> ctxMap = new HashMap<>();
            ctxMap.put("domainId", domainInst.getDomainId());
            JDSActionContext.getActionContext().getContext().putAll(ctxMap);
            EUModule euModule = ESDFacrory.getAdminESDClient().getModule(currentClassName, projectName);
            ModuleComponent moduleComponent = euModule.getComponent();
            MethodConfig methodConfig = null;
            try {
                methodConfig = moduleComponent.getMethodAPIBean();
                if (methodConfig == null) {
                    methodConfig = ESDFacrory.getAdminESDClient().getMethodAPIBean(euModule.getPath(), projectName);
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }

            Set<String> esdClassNames = new HashSet<>();
            esdClassNames.add(methodConfig.getSourceClassName());
            Set<Class> classes = methodConfig.getOtherClass();
            for (Class clazz : classes) {
                if (clazz != null) {
                    esdClassNames.add(clazz.getName());
                }
            }

            DSMFactory.getInstance().getAggregationManager().delAggEntity(domainInst.getDomainId(), esdClassNames, projectName, false);
            CustomViewFactory.getInstance().reLoad();
        } catch (Exception e) {
            e.printStackTrace();
            chrome.printError(e.getMessage());
            ((ErrorResultModel) resultModel).setErrdes(e.getMessage());
        }
        return resultModel;
    }


    public ChromeProxy getCurrChromeDriver() {
        ChromeProxy chrome = JDSActionContext.getActionContext().Par("$currChromeDriver", ChromeProxy.class);
        return chrome;
    }
}
